package model

import (
	"context"
	"fmt"

	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ UsersModel = (*customUsersModel)(nil)

type (
	// UsersModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUsersModel.
	UsersModel interface {
		usersModel
		withSession(session sqlx.Session) UsersModel
		FindByUsername(ctx context.Context, username string) (*Users, error)
		FindById(ctx context.Context, id int64) (*Users, error)
		FindUserPage(ctx context.Context, offset int, size int) ([]Users, error)
		FindUserCount(ctx context.Context) (int, error)
		FindByApiKey(ctx context.Context, key string) (*Users, error)
	}

	customUsersModel struct {
		*defaultUsersModel
	}
)

func (m *customUsersModel) FindByApiKey(ctx context.Context, key string) (*Users, error) {
	query := fmt.Sprintf("select %s from %s where `api_key` = ? limit 1", usersRows, m.table)
	var user Users
	err := m.conn.QueryRowCtx(ctx, &user, query, key)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

func (m *customUsersModel) FindUserCount(ctx context.Context) (int, error) {
	query := fmt.Sprintf("select count(*) from %s", m.table)
	var count int
	err := m.conn.QueryRowCtx(ctx, &count, query)
	if err != nil {
		return 0, err
	}
	return count, err
}

func (m *customUsersModel) FindUserPage(ctx context.Context, offset int, size int) ([]Users, error) {
	query := fmt.Sprintf("select %s from %s limit  ?,? ", usersRows, m.table)
	var users []Users
	err := m.conn.QueryRowsCtx(ctx, &users, query, offset, size)
	if err != nil {
		return nil, err
	}
	return users, nil
}

func (m *customUsersModel) FindById(ctx context.Context, id int64) (*Users, error) {

	query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", usersRows, m.table)
	var user Users
	err := m.conn.QueryRowCtx(ctx, &user, query, id)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

func (m *customUsersModel) FindByUsername(ctx context.Context, username string) (*Users, error) {
	//TODO implement me
	query := fmt.Sprintf("select %s from %s where `username` = ? limit 1", usersRows, m.table)
	var user Users
	err := m.conn.QueryRowCtx(ctx, &user, query, username)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// NewUsersModel returns a model for the database table.
func NewUsersModel(conn sqlx.SqlConn) UsersModel {
	return &customUsersModel{
		defaultUsersModel: newUsersModel(conn),
	}
}

func (m *customUsersModel) withSession(session sqlx.Session) UsersModel {
	return NewUsersModel(sqlx.NewSqlConnFromSession(session))
}
